package org.Yiran.timetale_re.energy;

import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.energy.IEnergyStorage;

/**
 * 电力基础类 - 为各种能源系统提供统一的电力管理接口
 * <p>
 * 这是一个抽象类，实现了Forge的IEnergyStorage接口和INBTSerializable接口，
 * 提供了能量存储的基本功能，包括能量的接收、提取、存储和NBT序列化。
 * 子类可以继承此类并实现特定的能源系统，如Forge Energy、Tesla等。
 * </p>
 */
public abstract class BaseEnergyStorage implements IEnergyStorage, INBTSerializable<CompoundTag> {
    
    // ============================== 实例变量 ==============================
    
    protected int energy;          // 当前存储的能量值
    protected int capacity;        // 能量存储容量
    protected int maxReceive;      // 最大接收速率
    protected int maxExtract;      // 最大提取速率

    // ============================== 构造方法 ==============================
    
    /**
     * 构造函数 - 仅指定容量
     * <p>
     * 使用容量值同时设置最大接收和提取速率，初始能量为0
     * </p>
     * 
     * @param capacity 容量值
     */
    public BaseEnergyStorage(int capacity) {
        this(capacity, capacity, capacity, 0);
    }

    /**
     * 构造函数 - 指定容量和最大传输速率
     * <p>
     * 使用相同的值设置最大接收和提取速率，初始能量为0
     * </p>
     * 
     * @param capacity 容量值
     * @param maxTransfer 最大传输速率（接收和提取）
     */
    public BaseEnergyStorage(int capacity, int maxTransfer) {
        this(capacity, maxTransfer, maxTransfer, 0);
    }

    /**
     * 构造函数 - 分别指定接收和提取的最大速率
     * <p>
     * 初始能量为0
     * </p>
     * 
     * @param capacity 容量值
     * @param maxReceive 最大接收速率
     * @param maxExtract 最大提取速率
     */
    public BaseEnergyStorage(int capacity, int maxReceive, int maxExtract) {
        this(capacity, maxReceive, maxExtract, 0);
    }

    /**
     * 构造函数 - 完整参数
     * <p>
     * 完整指定所有参数，包括容量、接收速率、提取速率和初始能量
     * </p>
     * 
     * @param capacity 容量值
     * @param maxReceive 最大接收速率
     * @param maxExtract 最大提取速率
     * @param initialEnergy 初始能量值
     */
    public BaseEnergyStorage(int capacity, int maxReceive, int maxExtract, int initialEnergy) {
        this.capacity = capacity;
        this.maxReceive = maxReceive;
        this.maxExtract = maxExtract;
        this.energy = Math.max(0, Math.min(capacity, initialEnergy));
    }

    // ============================== 能量操作方法 ==============================
    
    /**
     * 接收能量
     * <p>
     * 尝试向存储中添加能量，如果simulate为false，则实际修改存储中的能量值
     * </p>
     * 
     * @param maxReceive 最大接收量
     * @param simulate 是否为模拟操作（不实际修改能量值）
     * @return 实际接收的能量值
     */
    @Override
    public int receiveEnergy(int maxReceive, boolean simulate) {
        if (!canReceive()) {
            return 0;
        }

        int limitedReceive = Math.min(maxReceive, getMaxEnergyStored() - getEnergyStored());

        if (!simulate) {
            energy += limitedReceive;
        }

        return limitedReceive;
    }

    /**
     * 提取能量
     * <p>
     * 尝试从存储中提取能量，如果simulate为false，则实际修改存储中的能量值
     * </p>
     * 
     * @param maxExtract 最大提取量
     * @param simulate 是否为模拟操作（不实际修改能量值）
     * @return 实际提取的能量值
     */
    @Override
    public int extractEnergy(int maxExtract, boolean simulate) {
        if (!canExtract()) {
            return 0;
        }

        int limitedExtract = Math.min(maxExtract, getEnergyStored());

        if (!simulate) {
            energy -= limitedExtract;
        }

        return limitedExtract;
    }

    /**
     * 获取当前存储的能量值
     * 
     * @return 当前能量值
     */
    @Override
    public int getEnergyStored() {
        return energy;
    }

    /**
     * 获取最大能量存储容量
     * 
     * @return 最大容量值
     */
    @Override
    public int getMaxEnergyStored() {
        return capacity;
    }

    /**
     * 检查是否可以提取能量
     * 
     * @return 如果最大提取速率大于0则返回true，否则返回false
     */
    @Override
    public boolean canExtract() {
        return maxExtract > 0;
    }

    /**
     * 检查是否可以接收能量
     * 
     * @return 如果最大接收速率大于0则返回true，否则返回false
     */
    @Override
    public boolean canReceive() {
        return maxReceive > 0;
    }

    // ============================== NBT序列化方法 ==============================
    
    /**
     * 将能量存储数据序列化为NBT标签
     * <p>
     * 保存当前的能量值、容量、最大接收速率和最大提取速率
     * </p>
     * 
     * @return 包含能量存储数据的NBT标签
     */
    @Override
    public CompoundTag serializeNBT() {
        CompoundTag tag = new CompoundTag();
        tag.putInt("energy", energy);
        tag.putInt("capacity", capacity);
        tag.putInt("maxReceive", maxReceive);
        tag.putInt("maxExtract", maxExtract);
        return tag;
    }

    /**
     * 从NBT标签中反序列化能量存储数据
     * <p>
     * 恢复能量值、容量、最大接收速率和最大提取速率，并确保能量值在有效范围内
     * </p>
     * 
     * @param nbt 包含能量存储数据的NBT标签
     */
    @Override
    public void deserializeNBT(CompoundTag nbt) {
        energy = nbt.getInt("energy");
        capacity = nbt.getInt("capacity");
        maxReceive = nbt.getInt("maxReceive");
        maxExtract = nbt.getInt("maxExtract");
        
        // 确保能量值在有效范围内
        energy = Math.max(0, Math.min(capacity, energy));
    }

    // ============================== 内部设置方法 ==============================
    
    /**
     * 设置能量值（内部使用）
     * 
     * @param energy 能量值
     */
    public void setEnergy(int energy) {
        this.energy = energy;
    }

    /**
     * 设置容量（内部使用）
     * 
     * @param capacity 容量值
     */
    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }
}